// 音程听感训练器 - 核心逻辑文件

class IntervalTrainer {
    constructor() {
        this.synth = null;
        this.isPlaying = false;
        this.currentPlayingTimeout = null;
        this.practiceStats = {
            single: { correct: 0, wrong: 0, streak: 0 },
            multi: { correct: 0, wrong: 0, streak: 0 }
        };
        this.currentPracticeInterval = null;
        this.allIntervalsPlaylist = [];
        this.currentAllIntervalsIndex = 0;
        this.allIntervalsPlaying = false;
        this.practiceTimer = null;
        this.pianoIntervalPlaying = false; // 钢琴音程播放状态
        this.currentPianoPlayingOctave = null; // 当前播放的八度
        this.pianoPlayingTimeout = null; // 钢琴播放定时器
        this.currentTempo = 120; // 实时速度控制
        this.pianoTempo = 120; // 钢琴速度控制
        this.shouldLoop = false; // 循环播放标志
        this.shouldLoopAllIntervals = false; // 全音程循环标志
        this.isDemoScalePlaying = false; // 示范音阶播放标志
        
        this.init();
    }

    // 音阶定义
    scales = {
        'C': ['C', 'D', 'E', 'F', 'G', 'A', 'B'],
        'G': ['G', 'A', 'B', 'C', 'D', 'E', 'F#'],
        'D': ['D', 'E', 'F#', 'G', 'A', 'B', 'C#'],
        'A': ['A', 'B', 'C#', 'D', 'E', 'F#', 'G#'],
        'E': ['E', 'F#', 'G#', 'A', 'B', 'C#', 'D#'],
        'B': ['B', 'C#', 'D#', 'E', 'F#', 'G#', 'A#'],
        'F#': ['F#', 'G#', 'A#', 'B', 'C#', 'D#', 'E#'],
        'Db': ['Db', 'Eb', 'F', 'Gb', 'Ab', 'Bb', 'C'],
        'Ab': ['Ab', 'Bb', 'C', 'Db', 'Eb', 'F', 'G'],
        'Eb': ['Eb', 'F', 'G', 'Ab', 'Bb', 'C', 'D'],
        'Bb': ['Bb', 'C', 'D', 'Eb', 'F', 'G', 'A'],
        'F': ['F', 'G', 'A', 'Bb', 'C', 'D', 'E'],
        'Am': ['A', 'B', 'C', 'D', 'E', 'F', 'G'],
        'Em': ['E', 'F#', 'G', 'A', 'B', 'C', 'D'],
        'Bm': ['B', 'C#', 'D', 'E', 'F#', 'G', 'A'],
        'F#m': ['F#', 'G#', 'A', 'B', 'C#', 'D', 'E'],
        'C#m': ['C#', 'D#', 'E', 'F#', 'G#', 'A', 'B'],
        'G#m': ['G#', 'A#', 'B', 'C#', 'D#', 'E', 'F#'],
        'D#m': ['D#', 'E#', 'F#', 'G#', 'A#', 'B', 'C#'],
        'Bbm': ['Bb', 'C', 'Db', 'Eb', 'F', 'Gb', 'Ab'],
        'Fm': ['F', 'G', 'Ab', 'Bb', 'C', 'Db', 'Eb'],
        'Cm': ['C', 'D', 'Eb', 'F', 'G', 'Ab', 'Bb'],
        'Gm': ['G', 'A', 'Bb', 'C', 'D', 'Eb', 'F'],
        'Dm': ['D', 'E', 'F', 'G', 'A', 'Bb', 'C']
    };

    // 音程定义 (以半音数表示)
    intervals = {
        '纯一度': 0, '小二度': 1, '大二度': 2, '小三度': 3, '大三度': 4,
        '纯四度': 5, '三全音': 6, '纯五度': 7, '小六度': 8, '大六度': 9,
        '小七度': 10, '大七度': 11, '纯八度': 12
    };

    // 音程分类
    intervalCategories = {
        consonant: ['纯一度', '小三度', '大三度', '纯四度', '纯五度', '小六度', '大六度', '纯八度'],
        dissonant: ['小二度', '大二度', '三全音', '小七度', '大七度'],
        perfect: ['纯一度', '纯四度', '纯五度', '纯八度'],
        major: ['大二度', '大三度', '大六度', '大七度'],
        minor: ['小二度', '小三度', '小六度', '小七度']
    };

    // 音符到MIDI音符的映射
    noteToMidi = {
        'C': 60, 'C#': 61, 'Db': 61, 'D': 62, 'D#': 63, 'Eb': 63, 'E': 64, 'E#': 65,
        'F': 65, 'F#': 66, 'Gb': 66, 'G': 67, 'G#': 68, 'Ab': 68, 'A': 69, 'A#': 70,
        'Bb': 70, 'B': 71, 'B#': 72
    };

    async init() {
        console.log('开始初始化 IntervalTrainer...');
        await this.initializeTone();
        console.log('音频初始化完成');
        this.bindEvents();
        console.log('事件绑定完成');
        this.loadSettings();
        this.generateMultiIntervalButtons();
        this.generateScaleCheckboxes();
        this.generatePianoKeyboard();
        console.log('钢琴键盘生成完成');
        this.loadStats();
        this.initializeInfoDisplay(); // 初始化信息显示
        console.log('IntervalTrainer 初始化完成！');
    }

    async initializeTone() {
        try {
            // 使用采样器加载真实钢琴音色
            this.synth = new Tone.Sampler({
                urls: {
                    "C4": "https://tonejs.github.io/audio/salamander/C4.mp3",
                    "D#4": "https://tonejs.github.io/audio/salamander/Ds4.mp3",
                    "F#4": "https://tonejs.github.io/audio/salamander/Fs4.mp3",
                    "A4": "https://tonejs.github.io/audio/salamander/A4.mp3",
                    "C5": "https://tonejs.github.io/audio/salamander/C5.mp3",
                    "D#5": "https://tonejs.github.io/audio/salamander/Ds5.mp3",
                    "F#5": "https://tonejs.github.io/audio/salamander/Fs5.mp3",
                    "A5": "https://tonejs.github.io/audio/salamander/A5.mp3",
                },
                release: 1,
                baseUrl: ""
            }).toDestination();
            
            // 添加轻微的混响效果
            const reverb = new Tone.Reverb({
                decay: 1.5,
                wet: 0.2
            }).toDestination();
            
            this.synth.connect(reverb);
            
            console.log('Tone.js 真实钢琴音色初始化成功');
        } catch (error) {
            console.error('Tone.js 初始化失败，回退到合成音色:', error);
            // 如果采样器加载失败，回退到改进的合成音色
            this.initializeFallbackSynth();
        }
    }
    
    // 备用合成器（如果采样器加载失败）
    initializeFallbackSynth() {
        this.synth = new Tone.PolySynth(Tone.Synth, {
            oscillator: {
                partials: [1, 0.7, 0.5, 0.3, 0.1], // 添加泛音，更像钢琴
                type: "custom"
            },
            envelope: {
                attack: 0.002,
                decay: 0.3,
                sustain: 0.05,
                release: 2.5 // 更长的释音，模拟钢琴的自然衰减
            },
            volume: -8
        }).toDestination();
        
        // 添加低通滤波器，让声音更温暖
        const filter = new Tone.Filter({
            frequency: 3000,
            type: "lowpass",
            rolloff: -12
        });
        
        const reverb = new Tone.Reverb({
            decay: 2,
            wet: 0.25
        }).toDestination();
        
        this.synth.connect(filter);
        filter.connect(reverb);
    }

    bindEvents() {
        // 播放速度滑块（支持实时调整）
        document.getElementById('tempoSlider').addEventListener('input', (e) => {
            const newTempo = e.target.value;
            document.getElementById('tempoValue').textContent = newTempo;
            // 实时更新单音程播放的速度
            this.currentTempo = parseInt(newTempo);
        });
        
        // 全音程播放速度滑块（支持实时调整）
        document.getElementById('allIntervalsTempo').addEventListener('input', (e) => {
            const newTempo = e.target.value;
            document.getElementById('allTempoValue').textContent = newTempo;
            // 实时更新全音程播放的速度
            if (this.allIntervalsPlaying && this.allIntervalsPlaylist) {
                // 更新播放列表中的速度
                this.allIntervalsPlaylist.forEach(item => {
                    item.tempo = parseInt(newTempo);
                });
            }
        });

        // 单音程播放
        document.getElementById('playScaleIntervals').addEventListener('click', () => this.playScaleIntervals());
        document.getElementById('stopPlaying').addEventListener('click', () => this.stopPlaying());

        // 全音程播放
        document.getElementById('playAllIntervals').addEventListener('click', () => this.playAllIntervals());
        document.getElementById('pauseAllIntervals').addEventListener('click', () => this.pauseAllIntervals());
        document.getElementById('stopAllIntervals').addEventListener('click', () => this.stopAllIntervals());

        // 音程练习（原多音阶练习）
        document.getElementById('startMultiPractice').addEventListener('click', () => this.startMultiScalePractice());
        document.getElementById('playMultiPracticeInterval').addEventListener('click', () => this.playCurrentMultiPracticeInterval());
        document.getElementById('resetMultiStats').addEventListener('click', () => this.resetStats('multi'));

        // 音量和八度控制
        document.getElementById('pianoVolume').addEventListener('input', (e) => {
            document.getElementById('volumeValue').textContent = e.target.value;
            if (this.synth) {
                this.synth.volume.value = -30 + (parseInt(e.target.value) * 0.3);
            }
        });

        document.getElementById('pianoOctave').addEventListener('input', (e) => {
            document.getElementById('octaveValue').textContent = e.target.value;
        });
        
        // 钢琴速度控制（支持实时调整）
        document.getElementById('pianoTempo').addEventListener('input', (e) => {
            const newTempo = e.target.value;
            document.getElementById('pianoTempoValue').textContent = newTempo;
            // 实时更新钢琴音程播放的速度
            this.pianoTempo = parseInt(newTempo);
        });

        // 示范音阶播放
        document.getElementById('playDemoScale').addEventListener('click', () => {
            if (this.isDemoScalePlaying) {
                // 如果正在播放，则停止
                this.stopDemoScale();
            } else {
                // 开始播放
                this.playDemoScale();
            }
        });

        // 保存设置
        ['scaleSelect', 'directionSelect', 'fixedRoot', 'hideAnswer', 'intervalFilter', 'randomOrder', 'practiceMode', 'pianoDirection', 'pianoFixedRoot', 'pianoTempo', 'allIntervalsDirection', 'allIntervalsTempo'].forEach(id => {
            const element = document.getElementById(id);
            if (element) {
                element.addEventListener('change', () => {
                    this.saveSettings();
                    // 播放方向变更时输出日志
                    if (id === 'directionSelect' || id === 'allIntervalsDirection' || id === 'pianoDirection') {
                        console.log(`播放方向已更改为: ${element.value}`);
                    }
                });
            }
        });
    }

    // 初始化信息显示
    initializeInfoDisplay() {
        const infoDiv = document.getElementById('currentNoteInfo')?.querySelector('.alert');
        const nameElement = document.getElementById('currentNoteName');
        const freqElement = document.getElementById('currentNoteFreq');
        const freqUnitElement = document.getElementById('freqUnit');
        
        if (infoDiv) {
            infoDiv.style.display = 'block';
        }
        if (nameElement) nameElement.textContent = '点击钢琴键或播放音程';
        if (freqElement) freqElement.textContent = '';
        if (freqUnitElement) freqUnitElement.textContent = '';
        
        // 初始化钢琴速度显示
        const pianoTempoElement = document.getElementById('pianoTempoValue');
        if (pianoTempoElement) {
            pianoTempoElement.textContent = this.pianoTempo;
        }
    }

    // 生成钢琴键盘
    generatePianoKeyboard() {
        const container = document.getElementById('pianoKeyboard');
        container.innerHTML = '';
        
        // 科学音高记号法的音符名称
        const noteNames = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'];
        const blackKeys = ['C#', 'D#', 'F#', 'G#', 'A#'];
        
        // 生成七个八度（C1-C7）
        for (let octave = 1; octave <= 7; octave++) {
            const octaveDiv = document.createElement('div');
            octaveDiv.className = 'piano-octave';
            
            // 八度标签（使用亥姆霍兹记号法）
            const label = document.createElement('div');
            label.className = 'octave-label';
            const helmholtzLabel = this.midiToHelmholtz('C', octave);
            label.textContent = `${helmholtzLabel}组`;
            octaveDiv.appendChild(label);
            
            // 键盘区域
            const keysDiv = document.createElement('div');
            keysDiv.className = 'piano-keys';
            
            // 生成该八度的所有键
            noteNames.forEach(noteName => {
                const button = document.createElement('button');
                button.className = `piano-key ${blackKeys.includes(noteName) ? 'black' : 'white'}`;
                
                // 使用亥姆霍兹记号法显示
                const helmholtzName = this.midiToHelmholtz(noteName, octave);
                button.textContent = helmholtzName;
                button.dataset.note = noteName;
                button.dataset.octave = octave;
                
                button.addEventListener('click', () => {
                    console.log(`点击了钢琴键: ${noteName}${octave}`);
                    this.playPianoKey(noteName, octave, button);
                });
                
                keysDiv.appendChild(button);
            });
            
            // 添加播放图标按钮
            const playButton = document.createElement('button');
            playButton.className = 'btn btn-outline-light btn-sm ms-2';
            playButton.innerHTML = '🎵';
            playButton.title = `播放${helmholtzLabel}组音程练习`;
            playButton.id = `piano-play-${octave}`; // 添加ID以便后续控制
            playButton.addEventListener('click', () => {
                this.toggleOctaveIntervals(octave, playButton);
            });
            
            octaveDiv.appendChild(keysDiv);
            octaveDiv.appendChild(playButton);
            container.appendChild(octaveDiv);
        }
    }

    // 播放钢琴键
    async playPianoKey(noteName, octave, buttonElement) {
        console.log(`开始播放钢琴键: ${noteName}${octave}`);
        
        // 先显示视觉反馈
        buttonElement.classList.add('active');
        setTimeout(() => {
            buttonElement.classList.remove('active');
        }, 300);
        
        if (!this.synth) {
            console.error('音频合成器未初始化，尝试重新初始化...');
            await this.initializeTone();
            if (!this.synth) {
                console.error('音频合成器初始化失败');
                return;
            }
        }
        
        try {
            // 确保 Tone.js 已启动
            if (Tone.context.state !== 'running') {
                await Tone.start();
                console.log('Tone.js 已启动');
            }
            
            // 计算MIDI音符
            const baseNote = this.noteToMidi[noteName];
            if (baseNote === undefined) {
                console.error(`未知音符: ${noteName}`);
                return;
            }
            
            const midiNote = baseNote + (octave - 4) * 12;
            const frequency = Tone.Frequency(midiNote, "midi").toFrequency();
            
            console.log(`MIDI: ${midiNote}, 频率: ${frequency.toFixed(2)}Hz`);
            
            // 播放音符
            this.synth.triggerAttackRelease(frequency, 0.8);
            
            // 显示当前音符信息（使用亥姆霍兹记号法）
            const helmholtzName = this.midiToHelmholtz(noteName, octave);
            this.showCurrentNoteInfo(helmholtzName, frequency.toFixed(2));
            
            console.log(`播放钢琴键成功: ${helmholtzName}, 频率: ${frequency.toFixed(2)}Hz`);
            
        } catch (error) {
            console.error('播放钢琴键时出错:', error);
        }
    }

    // 显示当前音符信息
    showCurrentNoteInfo(noteName, frequency) {
        const infoDiv = document.getElementById('currentNoteInfo')?.querySelector('.alert');
        const nameElement = document.getElementById('currentNoteName');
        const freqElement = document.getElementById('currentNoteFreq');
        const freqUnitElement = document.getElementById('freqUnit');
        
        if (nameElement) nameElement.textContent = noteName;
        if (freqElement) freqElement.textContent = frequency;
        if (freqUnitElement) freqUnitElement.textContent = frequency ? 'Hz' : '';
        
        if (infoDiv) {
            infoDiv.style.display = 'block';
            
            // 3秒后恢复默认状态（而不是完全隐藏）
            setTimeout(() => {
                if (nameElement) nameElement.textContent = '点击钢琴键或播放音程';
                if (freqElement) freqElement.textContent = '';
                if (freqUnitElement) freqUnitElement.textContent = '';
            }, 3000);
        }
    }
    
    // 显示持续的音符信息（播放时不闪烁）
    showPersistentNoteInfo(info) {
        const infoDiv = document.getElementById('currentNoteInfo')?.querySelector('.alert');
        const nameElement = document.getElementById('currentNoteName');
        const freqElement = document.getElementById('currentNoteFreq');
        const freqUnitElement = document.getElementById('freqUnit');
        
        if (nameElement) nameElement.textContent = info;
        if (freqElement) freqElement.textContent = '';
        if (freqUnitElement) freqUnitElement.textContent = '';
        
        if (infoDiv) {
            infoDiv.style.display = 'block';
            // 播放时不自动隐藏，由停止播放时手动重置
        }
    }

    // 播放八度音阶
    async playOctaveScale(octave) {
        const noteNames = ['C', 'D', 'E', 'F', 'G', 'A', 'B', 'C'];
        
        this.isDemoScalePlaying = true; // 设置播放状态
        
        // 循环播放
        while (this.isDemoScalePlaying) {
            for (let i = 0; i < noteNames.length && this.isDemoScalePlaying; i++) {
                const noteName = noteNames[i];
                const noteOctave = i === 7 ? octave + 1 : octave; // 最后一个C是下一八度
                
                const baseNote = this.noteToMidi[noteName];
                const midiNote = baseNote + (noteOctave - 4) * 12;
                const frequency = Tone.Frequency(midiNote, "midi").toFrequency();
                
                await Tone.start();
                this.synth.triggerAttackRelease(frequency, 0.5);
                
                // 高亮对应按键
                const keyButton = document.querySelector(`[data-note="${noteName}"][data-octave="${noteOctave}"]`);
                if (keyButton) {
                    keyButton.classList.add('active');
                    setTimeout(() => {
                        keyButton.classList.remove('active');
                    }, 400);
                }
                
                // 显示音符信息（使用亥姆霍兹记号法）
                const helmholtzName = this.midiToHelmholtz(noteName, noteOctave);
                this.showCurrentNoteInfo(helmholtzName, frequency.toFixed(2));
                
                await new Promise(resolve => setTimeout(resolve, 600));
            }
        }
    }

    // 切换八度音程播放状态
    toggleOctaveIntervals(octave, buttonElement) {
        if (this.pianoIntervalPlaying && this.currentPianoPlayingOctave === octave) {
            // 如果正在播放同一八度，停止播放
            this.stopOctaveIntervals();
        } else {
            // 停止其他播放，开始新的播放
            this.stopOctaveIntervals();
            this.playOctaveIntervals(octave, buttonElement);
        }
    }

    // 停止八度音程播放
    stopOctaveIntervals() {
        this.pianoIntervalPlaying = false;
        if (this.pianoPlayingTimeout) {
            clearTimeout(this.pianoPlayingTimeout);
            this.pianoPlayingTimeout = null;
        }
        
        // 重置所有播放按钮的状态
        for (let octave = 1; octave <= 7; octave++) {
            const button = document.getElementById(`piano-play-${octave}`);
            if (button) {
                button.innerHTML = '🎵';
                button.className = 'btn btn-outline-light btn-sm ms-2';
                // 使用亥姆霍兹记号法表示八度
                const helmholtzLabel = this.getOctaveHelmholtzLabel(octave);
                button.title = `播放${helmholtzLabel}组音程练习`;
            }
        }
        
        // 播放时信息栏保持显示，停止后重置为默认状态
        const infoDiv = document.getElementById('currentNoteInfo')?.querySelector('.alert');
        const nameElement = document.getElementById('currentNoteName');
        const freqElement = document.getElementById('currentNoteFreq');
        const freqUnitElement = document.getElementById('freqUnit');
        
        if (infoDiv) {
            infoDiv.style.display = 'block';
        }
        if (nameElement) nameElement.textContent = '点击钢琴键或播放音程';
        if (freqElement) freqElement.textContent = '';
        if (freqUnitElement) freqUnitElement.textContent = '';
        
        this.currentPianoPlayingOctave = null;
        console.log('停止钢琴音程播放');
    }

    // 播放八度音程（按单音程播放策略）
    async playOctaveIntervals(octave, buttonElement) {
        // 设置播放状态
        this.pianoIntervalPlaying = true;
        this.currentPianoPlayingOctave = octave;
        
        // 更新按钮状态
        if (buttonElement) {
            buttonElement.innerHTML = '⏹️';
            buttonElement.className = 'btn btn-warning btn-sm ms-2';
            buttonElement.title = `停止${octave}组音程播放`;
        }
        
        // 获取钢琴设置
        const pianoDirection = document.getElementById('pianoDirection')?.value || 'ascending';
        const pianoFixedRoot = document.getElementById('pianoFixedRoot')?.checked || false;
        
        // 构建该八度的音符数组（C大调音阶）
        const scaleNotes = ['C', 'D', 'E', 'F', 'G', 'A', 'B'];
        const intervals = [];
        
        if (pianoFixedRoot) {
            // 固定根音：所有音程都从主音C开始
            const root = 'C';
            for (let i = 1; i < scaleNotes.length; i++) {
                intervals.push([root, scaleNotes[i]]);
            }
            // 添加纯八度（从根音到下一八度的根音）
            intervals.push([root, root + '1']); // 纯八度
        } else {
            // 任意两音组合
            for (let i = 0; i < scaleNotes.length; i++) {
                for (let j = i + 1; j < scaleNotes.length; j++) {
                    intervals.push([scaleNotes[i], scaleNotes[j]]);
                }
            }
        }
        
        console.log(`开始播放${octave}组的音程练习，共${intervals.length}个音程`);
        
        // 循环播放
        while (this.pianoIntervalPlaying) {
            for (let i = 0; i < intervals.length && this.pianoIntervalPlaying; i++) {
                if (!this.pianoIntervalPlaying) break; // 检查是否被停止
                
                const [note1, note2] = intervals[i];
                
                // 计算音程信息（处理纯八度）
                let semitones;
                if (typeof note2 === 'string' && note2.endsWith('1')) {
                    // 纯八度：12个半音
                    semitones = 12;
                } else if (note2 === 'C' && note1 === 'C') {
                    // 如果是同一个音，但在不同八度，也是纯八度
                    semitones = 12;
                } else {
                    semitones = this.calculateSemitones(note1, note2);
                }
                const intervalName = this.getIntervalName(semitones);
                
                // 实时获取播放方向设置
                const currentPianoDirection = document.getElementById('pianoDirection')?.value || 'ascending';
                let playDirection = currentPianoDirection;
                if (currentPianoDirection === 'random') {
                    playDirection = Math.random() < 0.5 ? 'ascending' : 'descending';
                }
                
                // 根据实际播放方向显示信息（持续显示，不闪烁）
                let displayNote1 = this.midiToHelmholtz(note1, octave);
                let displayNote2;
                
                if (typeof note2 === 'string' && note2.endsWith('1')) {
                    // 纯八度情况
                    const actualNote2 = note2.slice(0, -1);
                    displayNote2 = this.midiToHelmholtz(actualNote2, octave + 1);
                } else if (note2 === 'C' && note1 === 'C') {
                    // 同样的C但在不同八度
                    displayNote2 = this.midiToHelmholtz(note2, octave + 1);
                } else {
                    const displayOctave2 = (note2 === 'C' && note1 !== 'C') ? 
                        (octave === 7 ? 8 : octave + 1) : octave;
                    displayNote2 = this.midiToHelmholtz(note2, displayOctave2);
                }
                
                const displayInfo = playDirection === 'ascending' ? 
                    `${intervalName}: ${displayNote1} → ${displayNote2}` :
                    `${intervalName}: ${displayNote2} → ${displayNote1}`;
                this.showPersistentNoteInfo(displayInfo);
                
                // 播放音程
                await this.playOctaveInterval(note1, note2, octave, playDirection);
                
                // 使用实时钢琴速度计算等待间隔（使用可中断的timeout）
                const intervalGap = (60 / this.pianoTempo) * 1000; // 转换为毫秒
                await new Promise((resolve) => {
                    this.pianoPlayingTimeout = setTimeout(resolve, intervalGap);
                });
            }
        }
        
        // 播放完成时重置状态，但不调用stopOctaveIntervals（避免递归）
        console.log(`${octave}组音程播放一轮完成，准备重复`);
    }
    
    // 播放八度内的单个音程
    async playOctaveInterval(note1, note2, octave, direction = 'ascending') {
        if (!this.synth) return;
        
        await Tone.start();
        
        // 处理特殊情况：如果是纯八度，第二个音是下一八度的C
        // 但要确保不超出C7的范围
        let octave2 = octave;
        if (note2 === 'C' && note1 !== 'C' && octave < 7) {
            octave2 = octave + 1;
        } else if (note2 === 'C' && note1 !== 'C' && octave === 7) {
            // C7八度的纯八度音程，使用C8（但不高亮键盘）
            octave2 = 8;
        }
        
        const baseNote1 = this.noteToMidi[note1];
        const baseNote2 = this.noteToMidi[note2];
        const midiNote1 = baseNote1 + (octave - 4) * 12;
        const midiNote2 = baseNote2 + (octave2 - 4) * 12;
        
        const frequency1 = Tone.Frequency(midiNote1, "midi").toFrequency();
        const frequency2 = Tone.Frequency(midiNote2, "midi").toFrequency();
        
        if (direction === 'ascending') {
            this.synth.triggerAttackRelease(frequency1, 0.8);
            // 高亮第一个键
            this.highlightPianoKey(note1, octave);
            
            // 使用实时钢琴速度计算音符间的延迟
            const noteDelay = (60 / this.pianoTempo) * 1000;
            await new Promise(resolve => setTimeout(resolve, noteDelay));
            
            this.synth.triggerAttackRelease(frequency2, 0.8);
            // 高亮第二个键（只有在键盘范围内才高亮）
            if (octave2 <= 7) {
                this.highlightPianoKey(note2, octave2);
            }
        } else {
            this.synth.triggerAttackRelease(frequency2, 0.8);
            if (octave2 <= 7) {
                this.highlightPianoKey(note2, octave2);
            }
            
            // 使用实时钢琴速度计算音符间的延迟
            const noteDelay = (60 / this.pianoTempo) * 1000;
            await new Promise(resolve => setTimeout(resolve, noteDelay));
            
            this.synth.triggerAttackRelease(frequency1, 0.8);
            this.highlightPianoKey(note1, octave);
        }
    }
    
    // 高亮钢琴键
    highlightPianoKey(noteName, octave) {
        const keyButton = document.querySelector(`[data-note="${noteName}"][data-octave="${octave}"]`);
        if (keyButton) {
            keyButton.classList.add('active');
            setTimeout(() => {
                keyButton.classList.remove('active');
            }, 800);
        }
    }

    // 将MIDI音符转换为亥姆霍兹记号法
    midiToHelmholtz(note, octave) {
        // 处理升降号
        let noteBase = note.replace('#', '♯').replace('b', '♭');
        
        if (octave <= 2) {
            // 大字组和大字一组：使用大写字母
            if (octave === 1) {
                return noteBase.toUpperCase() + '₁'; // 大字一组
            } else if (octave === 2) {
                return noteBase.toUpperCase(); // 大字组
            }
        } else {
            // 小字组：使用小写字母
            const lowerNote = noteBase.toLowerCase();
            if (octave === 3) {
                return lowerNote; // 小字组
            } else if (octave === 4) {
                return lowerNote + '¹'; // 小字一组
            } else if (octave === 5) {
                return lowerNote + '²'; // 小字二组
            } else if (octave === 6) {
                return lowerNote + '³'; // 小字三组
            } else if (octave === 7) {
                return lowerNote + '⁴'; // 小字四组
            }
        }
        
        // 默认返回科学记号法作为备用
        return note + octave;
    }
    
    // 获取八度的亥姆霍兹标签
    getOctaveHelmholtzLabel(octave) {
        const helmholtzLabel = this.midiToHelmholtz('C', octave);
        return helmholtzLabel.replace(/[¹²³⁴₁]/g, ''); // 移除上标下标，只保留字母
    }
    
    // 计算音符在音阶中的亥姆霍兹表示
    getNoteHelmholtzInScale(note, scale, isSecondNote = false, firstNote = null) {
        const scaleNotes = this.scales[scale];
        const noteIndex = scaleNotes.indexOf(note);
        
        if (noteIndex === -1) {
            // 如果不在音阶中，使用默认八度
            return this.midiToHelmholtz(note, 4);
        }
        
        let octave = 4; // 默认从小字一组开始
        
        if (isSecondNote && firstNote) {
            // 检查是否需要升八度
            const firstNoteIndex = scaleNotes.indexOf(firstNote);
            if (firstNoteIndex !== -1) {
                const midi1 = this.noteToMidi[firstNote];
                const midi2 = this.noteToMidi[note];
                if (midi2 <= midi1) {
                    octave = 5; // 升到小字二组
                }
            }
        }
        
        return this.midiToHelmholtz(note, octave);
    }
    calculateSemitonesInScale(note1, note2, scale) {
        const scaleNotes = this.scales[scale];
        const note1Index = scaleNotes.indexOf(note1);
        const note2Index = scaleNotes.indexOf(note2);
        
        if (note1Index === -1 || note2Index === -1) {
            // 如果音符不在音阶中，使用标准计算
            return this.calculateSemitones(note1, note2);
        }
        
        // 获取音符的MIDI值
        const midi1 = this.noteToMidi[note1];
        let midi2 = this.noteToMidi[note2];
        
        // 在音阶中，如果note2的MIDI值小于note1，说明它应该在下一个八度
        // 例如：G大调中G(67) → C(60)，应该是G → C(下一八度)
        if (midi2 <= midi1) {
            midi2 += 12; // 加上一个八度
        }
        
        const semitones = Math.abs(midi2 - midi1);
        console.log(`${scale}音阶: ${note1}(MIDI:${midi1}) → ${note2}(MIDI:${midi2 > this.noteToMidi[note2] ? this.noteToMidi[note2] + '+12' : this.noteToMidi[note2]}) = ${semitones}半音`);
        return semitones;
    }
    
    // 计算两个音符之间的半音数
    calculateSemitones(note1, note2) {
        const midi1 = this.noteToMidi[note1];
        const midi2 = this.noteToMidi[note2];
        return Math.abs(midi2 - midi1);
    }

    // 获取音程名称
    getIntervalName(semitones) {
        for (const [name, value] of Object.entries(this.intervals)) {
            if (value === semitones) return name;
        }
        return '未知音程';
    }

    // 播放音符（支持八度偏移）
    async playNoteWithOctave(note, octaveOffset = 0, duration = 1.0) {
        if (!this.synth) return;
        await Tone.start();
        const midi = this.noteToMidi[note] + octaveOffset;
        const frequency = Tone.Frequency(midi, "midi").toFrequency();
        
        // 使用更自然的钢琴播放方式
        this.synth.triggerAttackRelease(frequency, duration, undefined, 0.8);
    }

    // 播放音符
    async playNote(note, duration = 1.0) {
        if (!this.synth) return;
        await Tone.start();
        const midi = this.noteToMidi[note];
        const frequency = Tone.Frequency(midi, "midi").toFrequency();
        
        // 使用更自然的钢琴播放方式
        this.synth.triggerAttackRelease(frequency, duration, undefined, 0.8);
    }

    // 播放音程（支持音阶内八度处理）
    async playInterval(note1, note2, direction = 'ascending', gap = 1.0, scale = null) {
        if (!this.synth) return;
        await Tone.start();
        
        // 处理纯八度的情况（note2可能包含八度标记）
        let actualNote1 = note1;
        let actualNote2 = note2;
        let octaveOffset1 = 0;
        let octaveOffset2 = 0;
        
        // 检查是否是纯八度（note2以'1'结尾）
        if (typeof note2 === 'string' && note2.endsWith('1')) {
            actualNote2 = note2.slice(0, -1); // 移除'1'后缀
            octaveOffset2 = 12; // 下一八度
        } else if (scale) {
            // 在音阶内检查是否需要八度调整
            const scaleNotes = this.scales[scale];
            const note1Index = scaleNotes.indexOf(note1);
            const note2Index = scaleNotes.indexOf(note2);
            
            if (note1Index !== -1 && note2Index !== -1) {
                const midi1 = this.noteToMidi[note1];
                const midi2 = this.noteToMidi[note2];
                if (midi2 <= midi1) {
                    octaveOffset2 = 12; // note2在下一个八度
                }
            }
        }
        
        if (direction === 'ascending') {
            // 上行：先播 note1，再播 note2
            console.log(`播放上行音程: ${actualNote1} → ${actualNote2}${octaveOffset2 ? '(下一八度)' : ''}`);
            await this.playNoteWithOctave(actualNote1, octaveOffset1, 1.0);
            await new Promise(resolve => setTimeout(resolve, gap * 1000));
            await this.playNoteWithOctave(actualNote2, octaveOffset2, 1.0);
        } else {
            // 下行：先播 note2，再播 note1 
            console.log(`播放下行音程: ${actualNote2}${octaveOffset2 ? '(下一八度)' : ''} → ${actualNote1}`);
            await this.playNoteWithOctave(actualNote2, octaveOffset2, 1.0);
            await new Promise(resolve => setTimeout(resolve, gap * 1000));
            await this.playNoteWithOctave(actualNote1, octaveOffset1, 1.0);
        }
    }

    // 播放单音阶的所有音程
    async playScaleIntervals() {
        const scale = document.getElementById('scaleSelect').value;
        const direction = document.getElementById('directionSelect').value;
        const fixedRoot = document.getElementById('fixedRoot').checked;
        const hideAnswer = document.getElementById('hideAnswer').checked;
        
        // 初始化当前速度
        this.currentTempo = parseInt(document.getElementById('tempoSlider').value);
        
        const scaleNotes = this.scales[scale];
        const intervals = [];
        
        if (fixedRoot) {
            const root = scaleNotes[0];
            for (let i = 1; i < scaleNotes.length; i++) {
                intervals.push([root, scaleNotes[i]]);
            }
            // 添加纯八度（从根音到下一八度的根音）
            intervals.push([root, root + '1']); // 纯八度
        } else {
            for (let i = 0; i < scaleNotes.length; i++) {
                for (let j = i + 1; j < scaleNotes.length; j++) {
                    intervals.push([scaleNotes[i], scaleNotes[j]]);
                }
            }
        }

        this.isPlaying = true;
        this.shouldLoop = true; // 添加循环标志
        const currentIntervalDiv = document.getElementById('currentInterval').querySelector('.alert');
        
        // 循环播放
        while (this.isPlaying && this.shouldLoop) {
            for (let i = 0; i < intervals.length && this.isPlaying && this.shouldLoop; i++) {
                const [note1, note2] = intervals[i];
                
                // 处理纯八度的半音数计算
                let semitones;
                if (typeof note2 === 'string' && note2.endsWith('1')) {
                    // 纯八度：12个半音
                    semitones = 12;
                } else {
                    // 使用音阶内的半音数计算
                    semitones = this.calculateSemitonesInScale(note1, note2, scale);
                }
                
                const intervalName = this.getIntervalName(semitones);
                
                // 实时获取播放方向设置
                const currentDirection = document.getElementById('directionSelect').value;
                let playDirection = currentDirection;
                if (currentDirection === 'random') {
                    playDirection = Math.random() < 0.5 ? 'ascending' : 'descending';
                }
                
                if (!hideAnswer) {
                    // 处理显示名称（使用亥姆霍兹记号法）
                    let displayNote1 = this.getNoteHelmholtzInScale(note1, scale, false);
                    let displayNote2;
                    
                    if (typeof note2 === 'string' && note2.endsWith('1')) {
                        // 纯八度情况
                        const actualNote2 = note2.slice(0, -1);
                        displayNote2 = this.getNoteHelmholtzInScale(actualNote2, scale, true, note1);
                    } else {
                        displayNote2 = this.getNoteHelmholtzInScale(note2, scale, true, note1);
                    }
                    
                    // 根据实际播放方向显示音符顺序
                    const displayNotes = playDirection === 'ascending' ? `${displayNote1} → ${displayNote2}` : `${displayNote2} → ${displayNote1}`;
                    document.getElementById('intervalName').textContent = intervalName;
                    document.getElementById('intervalNotes').textContent = displayNotes;
                    currentIntervalDiv.style.display = 'block';
                    console.log(`显示: ${intervalName} - ${displayNotes}, 播放方向: ${playDirection}`);
                }
                
                // 使用实时速度计算音符间隔时间
                const noteGap = 60 / this.currentTempo;
                await this.playInterval(note1, note2, playDirection, noteGap, scale);
                
                // 音程间的间隔时间也按实时速度控制
                const intervalGap = (60 / this.currentTempo) * 1000; // 转换为毫秒
                await new Promise(resolve => {
                    this.currentPlayingTimeout = setTimeout(resolve, intervalGap);
                });
            }
        }
        
        this.isPlaying = false;
        this.shouldLoop = false; // 停止循环
        if (hideAnswer) {
            currentIntervalDiv.style.display = 'none';
        }
    }

    // 停止播放
    stopPlaying() {
        this.isPlaying = false;
        this.shouldLoop = false; // 停止循环
        this.allIntervalsPlaying = false;
        if (this.currentPlayingTimeout) {
            clearTimeout(this.currentPlayingTimeout);
            this.currentPlayingTimeout = null;
        }
        
        // 检查DOM元素是否存在
        const currentIntervalAlert = document.querySelector('#currentInterval .alert');
        const progressDiv = document.querySelector('#allIntervalsProgress .progress');
        
        if (currentIntervalAlert) {
            currentIntervalAlert.style.display = 'none';
        }
        if (progressDiv) {
            progressDiv.style.display = 'none';
        }
    }

    // 播放所有音程
    async playAllIntervals() {
        const filter = document.getElementById('intervalFilter').value;
        const randomOrder = document.getElementById('randomOrder').checked;
        const direction = document.getElementById('allIntervalsDirection').value;
        const tempo = parseInt(document.getElementById('allIntervalsTempo').value);
        
        this.allIntervalsPlaylist = [];
        const scaleKeys = Object.keys(this.scales);
        
        for (const scaleKey of scaleKeys) {
            const scaleNotes = this.scales[scaleKey];
            for (let i = 0; i < scaleNotes.length; i++) {
                for (let j = i + 1; j < scaleNotes.length; j++) {
                    const note1 = scaleNotes[i];
                    const note2 = scaleNotes[j];
                    // 使用音阶内的半音数计算
                    const semitones = this.calculateSemitonesInScale(note1, note2, scaleKey);
                    const intervalName = this.getIntervalName(semitones);
                    
                    if (this.shouldIncludeInterval(intervalName, filter)) {
                        this.allIntervalsPlaylist.push({
                            scale: scaleKey, note1, note2, intervalName, semitones, direction, tempo
                        });
                    }
                }
            }
        }
        
        if (randomOrder) {
            this.shuffleArray(this.allIntervalsPlaylist);
        }
        
        this.currentAllIntervalsIndex = 0;
        this.allIntervalsPlaying = true;
        this.shouldLoopAllIntervals = true; // 添加全音程循环标志
        this.playNextAllInterval();
    }

    async playNextAllInterval() {
        if (!this.allIntervalsPlaying) {
            return;
        }
        
        // 如果到达末尾且循环模式开启，重置索引
        if (this.currentAllIntervalsIndex >= this.allIntervalsPlaylist.length) {
            if (this.shouldLoopAllIntervals) {
                this.currentAllIntervalsIndex = 0;
                console.log('全音程播放循环重新开始');
            } else {
                this.allIntervalsPlaying = false;
                document.getElementById('allIntervalsProgress').querySelector('.progress').style.display = 'none';
                document.getElementById('progressText').textContent = '播放完成';
                return;
            }
        }

        const item = this.allIntervalsPlaylist[this.currentAllIntervalsIndex];
        const progress = ((this.currentAllIntervalsIndex + 1) / this.allIntervalsPlaylist.length) * 100;
        const progressBar = document.getElementById('allIntervalsProgress').querySelector('.progress-bar');
        const progressDiv = document.getElementById('allIntervalsProgress').querySelector('.progress');
        
        // 实时获取播放方向设置
        const currentDirection = document.getElementById('allIntervalsDirection').value;
        let playDirection = currentDirection;
        if (currentDirection === 'random') {
            playDirection = Math.random() < 0.5 ? 'ascending' : 'descending';
        }
        
        // 根据实际播放方向显示音符（考虑跨八度，使用亥姆霍兹记号法）
        let displayNote1 = this.getNoteHelmholtzInScale(item.note1, item.scale, false);
        let displayNote2 = this.getNoteHelmholtzInScale(item.note2, item.scale, true, item.note1);
        
        const displayNotes = playDirection === 'ascending' ? `${displayNote1} → ${displayNote2}` : `${displayNote2} → ${displayNote1}`;
        
        progressDiv.style.display = 'block';
        progressBar.style.width = `${progress}%`;
        document.getElementById('progressText').textContent = 
            `播放中: ${this.currentAllIntervalsIndex + 1}/${this.allIntervalsPlaylist.length} - ${item.scale} - ${item.intervalName} (${displayNotes})`;
        
        // 使用实时的速度设置
        const currentTempo = parseInt(document.getElementById('allIntervalsTempo').value);
        const gap = 60 / currentTempo;
        await this.playInterval(item.note1, item.note2, playDirection, gap, item.scale);
        
        this.currentAllIntervalsIndex++;
        // 音程间的间隔时间也按实时速度控制
        const intervalGap = gap * 1000; // 转换为毫秒
        this.currentPlayingTimeout = setTimeout(() => {
            this.playNextAllInterval();
        }, intervalGap);
    }

    pauseAllIntervals() {
        this.allIntervalsPlaying = !this.allIntervalsPlaying;
        const btn = document.getElementById('pauseAllIntervals');
        if (this.allIntervalsPlaying) {
            btn.textContent = '暂停';
            this.playNextAllInterval();
        } else {
            btn.textContent = '继续';
            if (this.currentPlayingTimeout) {
                clearTimeout(this.currentPlayingTimeout);
            }
        }
    }

    stopAllIntervals() {
        this.allIntervalsPlaying = false;
        this.shouldLoopAllIntervals = false; // 停止循环
        this.currentAllIntervalsIndex = 0;
        if (this.currentPlayingTimeout) {
            clearTimeout(this.currentPlayingTimeout);
        }
        document.getElementById('allIntervalsProgress').querySelector('.progress').style.display = 'none';
        document.getElementById('progressText').textContent = '';
        document.getElementById('pauseAllIntervals').textContent = '暂停';
    }

    shouldIncludeInterval(intervalName, filter) {
        if (filter === 'all') return true;
        return this.intervalCategories[filter]?.includes(intervalName) || false;
    }

    shuffleArray(array) {
        for (let i = array.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [array[i], array[j]] = [array[j], array[i]];
        }
    }

    // 生成多音阶练习音程按钮
    generateMultiIntervalButtons() {
        const container = document.getElementById('multiIntervalButtons');
        if (!container) return;
        
        container.innerHTML = '';
        const intervalNames = Object.keys(this.intervals);
        
        intervalNames.forEach(intervalName => {
            const button = document.createElement('button');
            button.className = 'btn btn-outline-primary interval-btn col-md-3 col-6';
            button.textContent = intervalName;
            button.addEventListener('click', () => {
                this.checkMultiAnswer(intervalName);
            });
            container.appendChild(button);
        });
    }

    // 生成音阶复选框
    generateScaleCheckboxes() {
        const container = document.querySelector('.scales-selection');
        container.innerHTML = '';
        
        Object.keys(this.scales).forEach(scaleKey => {
            const div = document.createElement('div');
            div.className = 'form-check';
            
            const checkbox = document.createElement('input');
            checkbox.className = 'form-check-input';
            checkbox.type = 'checkbox';
            checkbox.id = `scale-${scaleKey}`;
            checkbox.value = scaleKey;
            
            const label = document.createElement('label');
            label.className = 'form-check-label';
            label.htmlFor = `scale-${scaleKey}`;
            label.textContent = scaleKey.includes('m') ? `${scaleKey.replace('m', '')}小调` : `${scaleKey}大调`;
            
            div.appendChild(checkbox);
            div.appendChild(label);
            container.appendChild(div);
        });
    }

    // 开始单音阶练习
    startSingleScalePractice() {
        const practiceArea = document.getElementById('practiceArea');
        const startBtn = document.getElementById('startPractice');
        
        console.log('开始单音阶练习');
        
        practiceArea.style.display = 'block';
        startBtn.textContent = '重新开始';
        
        // 确保音程按钮已生成
        if (document.querySelectorAll('#intervalButtons .interval-btn').length === 0) {
            console.log('重新生成音程按钮');
            this.generateIntervalButtons();
        }
        
        this.generateNewSinglePracticeInterval();
    }

    generateNewSinglePracticeInterval() {
        const scale = document.getElementById('practiceScaleSelect').value;
        const scaleNotes = this.scales[scale];
        
        let note1, note2;
        do {
            const index1 = Math.floor(Math.random() * scaleNotes.length);
            const index2 = Math.floor(Math.random() * scaleNotes.length);
            note1 = scaleNotes[index1];
            note2 = scaleNotes[index2];
        } while (note1 === note2);
        
        // 使用音阶内的半音数计算，确保音程计算准确
        const semitones = this.calculateSemitonesInScale(note1, note2, scale);
        const intervalName = this.getIntervalName(semitones);
        
        this.currentPracticeInterval = { note1, note2, intervalName, semitones };
        
        console.log(`生成新题目: ${note1} → ${note2}, 音程: ${intervalName} (${semitones}个半音)`);
        
        // 重置按钮状态
        document.querySelectorAll('#intervalButtons .interval-btn').forEach(btn => {
            btn.className = 'btn btn-outline-primary interval-btn col-md-3 col-6';
            btn.disabled = false;
        });
        
        document.getElementById('practiceResult').style.display = 'none';
        
        // 显示提示信息
        const playBtn = document.getElementById('playPracticeInterval');
        if (playBtn) {
            playBtn.textContent = '🔊 播放音程';
            playBtn.disabled = false;
        }
    }

    async playCurrentPracticeInterval() {
        if (this.currentPracticeInterval) {
            const { note1, note2 } = this.currentPracticeInterval;
            const scale = document.getElementById('practiceScaleSelect').value;
            console.log(`播放单音阶练习音程: ${note1} → ${note2} (${this.currentPracticeInterval.intervalName}) 音阶: ${scale}`);
            // 传递音阶信息，确保音程播放与显示的八度一致
            await this.playInterval(note1, note2, 'ascending', 1.0, scale);
        } else {
            console.log('没有当前练习音程可播放');
        }
    }

    checkSingleAnswer(selectedInterval) {
        if (!this.currentPracticeInterval) {
            console.log('没有当前练习音程，无法检查答案');
            return;
        }
        
        console.log(`用户选择: ${selectedInterval}, 正确答案: ${this.currentPracticeInterval.intervalName}`);
        
        const correct = selectedInterval === this.currentPracticeInterval.intervalName;
        const resultDiv = document.getElementById('practiceResult');
        
        // 更新按钮样式并禁用所有按钮
        document.querySelectorAll('#intervalButtons .interval-btn').forEach(btn => {
            btn.disabled = true; // 禁用所有按钮防止重复点击
            if (btn.textContent === selectedInterval) {
                btn.className = `btn ${correct ? 'btn-success correct' : 'btn-danger incorrect'} interval-btn col-md-3 col-6`;
            } else if (btn.textContent === this.currentPracticeInterval.intervalName) {
                btn.className = 'btn btn-success correct interval-btn col-md-3 col-6';
            }
        });
        
        // 更新统计
        if (correct) {
            this.practiceStats.single.correct++;
            this.practiceStats.single.streak++;
        } else {
            this.practiceStats.single.wrong++;
            this.practiceStats.single.streak = 0;
        }
        
        this.updateStatsDisplay('single');
        this.saveStats();
        
        // 显示结果（使用亥姆霍兹记号法）
        const practiceScale = document.getElementById('practiceScaleSelect').value;
        const displayNote1 = this.getNoteHelmholtzInScale(this.currentPracticeInterval.note1, practiceScale, false);
        const displayNote2 = this.getNoteHelmholtzInScale(this.currentPracticeInterval.note2, practiceScale, true, this.currentPracticeInterval.note1);
        
        resultDiv.className = `result-area mt-3 ${correct ? 'result-correct' : 'result-incorrect'}`;
        resultDiv.innerHTML = `
            <h5>${correct ? '✅ 正确！' : '❌ 错误'}</h5>
            <p>正确答案：${this.currentPracticeInterval.intervalName}</p>
            <p>音符：${displayNote1} → ${displayNote2} (${this.currentPracticeInterval.semitones}个半音)</p>
            <button class="btn btn-primary mt-2" onclick="trainer.generateNewSinglePracticeInterval()">下一题</button>
        `;
        resultDiv.style.display = 'block';
        
        console.log(`答案${correct ? '正确' : '错误'}，统计已更新`);
    }

    // 多音阶练习功能
    startMultiScalePractice() {
        const selectedScales = Array.from(document.querySelectorAll('.scales-selection input:checked')).map(cb => cb.value);
        
        if (selectedScales.length === 0) {
            alert('请至少选择一个音阶！');
            return;
        }
        
        this.selectedScales = selectedScales;
        const practiceArea = document.getElementById('multiPracticeArea');
        const startBtn = document.getElementById('startMultiPractice');
        
        practiceArea.style.display = 'block';
        startBtn.textContent = '重新开始';
        
        const practiceMode = document.getElementById('practiceMode').value;
        if (practiceMode === 'timed') {
            this.startPracticeTimer();
        }
        
        this.generateNewMultiPracticeInterval();
    }

    startPracticeTimer() {
        const timerDiv = document.getElementById('practiceTimer');
        const timeDisplay = document.getElementById('timeRemaining');
        
        timerDiv.style.display = 'block';
        let timeLeft = 180;
        
        this.practiceTimer = setInterval(() => {
            const minutes = Math.floor(timeLeft / 60);
            const seconds = timeLeft % 60;
            timeDisplay.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`;
            
            if (timeLeft <= 0) {
                this.endPracticeTimer();
            }
            timeLeft--;
        }, 1000);
    }

    endPracticeTimer() {
        if (this.practiceTimer) {
            clearInterval(this.practiceTimer);
            this.practiceTimer = null;
        }
        
        const timerDiv = document.getElementById('practiceTimer');
        timerDiv.style.display = 'none';
        
        const { correct, wrong } = this.practiceStats.multi;
        const total = correct + wrong;
        const accuracy = total > 0 ? Math.round((correct / total) * 100) : 0;
        
        alert(`时间到！
总题数：${total}
正确：${correct}
错误：${wrong}
正确率：${accuracy}%`);
    }

    generateNewMultiPracticeInterval() {
        const randomScale = this.selectedScales[Math.floor(Math.random() * this.selectedScales.length)];
        const scaleNotes = this.scales[randomScale];
        
        let note1, note2;
        do {
            const index1 = Math.floor(Math.random() * scaleNotes.length);
            const index2 = Math.floor(Math.random() * scaleNotes.length);
            note1 = scaleNotes[index1];
            note2 = scaleNotes[index2];
        } while (note1 === note2);
        
        // 使用音阶内的半音数计算，确保音程计算准确
        const semitones = this.calculateSemitonesInScale(note1, note2, randomScale);
        const intervalName = this.getIntervalName(semitones);
        
        this.currentMultiPracticeInterval = { scale: randomScale, note1, note2, intervalName, semitones };
        
        const scaleDisplayName = randomScale.includes('m') ? `${randomScale.replace('m', '')}小调` : `${randomScale}大调`;
        document.getElementById('currentScaleInfo').textContent = scaleDisplayName;
        
        document.querySelectorAll('#multiIntervalButtons .interval-btn').forEach(btn => {
            btn.className = 'btn btn-outline-primary interval-btn col-md-3 col-6';
        });
        
        document.getElementById('multiPracticeResult').style.display = 'none';
    }

    async playCurrentMultiPracticeInterval() {
        if (this.currentMultiPracticeInterval) {
            const { note1, note2, scale } = this.currentMultiPracticeInterval;
            console.log(`播放多音阶练习音程: ${note1} → ${note2} (${this.currentMultiPracticeInterval.intervalName}) 音阶: ${scale}`);
            // 传递音阶信息，确保音程播放与显示的八度一致
            await this.playInterval(note1, note2, 'ascending', 1.0, scale);
        } else {
            console.log('没有当前练习音程可播放');
        }
    }

    checkMultiAnswer(selectedInterval) {
        if (!this.currentMultiPracticeInterval) return;
        
        const correct = selectedInterval === this.currentMultiPracticeInterval.intervalName;
        const resultDiv = document.getElementById('multiPracticeResult');
        
        document.querySelectorAll('#multiIntervalButtons .interval-btn').forEach(btn => {
            if (btn.textContent === selectedInterval) {
                btn.className = `btn ${correct ? 'btn-success correct' : 'btn-danger incorrect'} interval-btn col-md-3 col-6`;
            } else if (btn.textContent === this.currentMultiPracticeInterval.intervalName) {
                btn.className = 'btn btn-success correct interval-btn col-md-3 col-6';
            }
        });
        
        if (correct) {
            this.practiceStats.multi.correct++;
            this.practiceStats.multi.streak++;
        } else {
            this.practiceStats.multi.wrong++;
            this.practiceStats.multi.streak = 0;
        }
        
        this.updateStatsDisplay('multi');
        this.saveStats();
        
        // 显示结果（使用亥姆霍兹记号法）
        const scaleDisplayName = this.currentMultiPracticeInterval.scale.includes('m') ? 
            `${this.currentMultiPracticeInterval.scale.replace('m', '')}小调` : 
            `${this.currentMultiPracticeInterval.scale}大调`;
        
        const displayNote1 = this.getNoteHelmholtzInScale(this.currentMultiPracticeInterval.note1, this.currentMultiPracticeInterval.scale, false);
        const displayNote2 = this.getNoteHelmholtzInScale(this.currentMultiPracticeInterval.note2, this.currentMultiPracticeInterval.scale, true, this.currentMultiPracticeInterval.note1);
        
        resultDiv.className = `result-area mt-3 ${correct ? 'result-correct' : 'result-incorrect'}`;
        resultDiv.innerHTML = `
            <h5>${correct ? '✅ 正确！' : '❌ 错误'}</h5>
            <p>正确答案：${this.currentMultiPracticeInterval.intervalName}</p>
            <p>音阶：${scaleDisplayName}</p>
            <p>音符：${displayNote1} → ${displayNote2}</p>
            <button class="btn btn-primary mt-2" onclick="trainer.generateNewMultiPracticeInterval()">下一题</button>
        `;
        resultDiv.style.display = 'block';
    }

    // 数据管理功能
    updateStatsDisplay(mode) {
        const prefix = mode === 'single' ? '' : 'multi';
        const stats = this.practiceStats[mode];
        const total = stats.correct + stats.wrong;
        const accuracy = total > 0 ? Math.round((stats.correct / total) * 100) : 0;
        
        document.getElementById(`${prefix}CorrectCount`).textContent = stats.correct;
        document.getElementById(`${prefix}WrongCount`).textContent = stats.wrong;
        document.getElementById(`${prefix}AccuracyRate`).textContent = `${accuracy}%`;
        document.getElementById(`${prefix}CurrentStreak`).textContent = stats.streak;
    }

    resetStats(mode) {
        this.practiceStats[mode] = { correct: 0, wrong: 0, streak: 0 };
        this.updateStatsDisplay(mode);
        this.saveStats();
    }

    saveStats() {
        localStorage.setItem('intervalTrainerStats', JSON.stringify(this.practiceStats));
    }

    loadStats() {
        const saved = localStorage.getItem('intervalTrainerStats');
        if (saved) {
            this.practiceStats = JSON.parse(saved);
        }
        this.updateStatsDisplay('single');
        this.updateStatsDisplay('multi');
    }

    saveSettings() {
        const settings = {
            scale: document.getElementById('scaleSelect')?.value,
            direction: document.getElementById('directionSelect')?.value,
            fixedRoot: document.getElementById('fixedRoot')?.checked,
            hideAnswer: document.getElementById('hideAnswer')?.checked,
            intervalFilter: document.getElementById('intervalFilter')?.value,
            randomOrder: document.getElementById('randomOrder')?.checked,
            practiceMode: document.getElementById('practiceMode')?.value,
            pianoDirection: document.getElementById('pianoDirection')?.value,
            pianoFixedRoot: document.getElementById('pianoFixedRoot')?.checked,
            pianoTempo: document.getElementById('pianoTempo')?.value,
            allIntervalsDirection: document.getElementById('allIntervalsDirection')?.value,
            allIntervalsTempo: document.getElementById('allIntervalsTempo')?.value
        };
        localStorage.setItem('intervalTrainerSettings', JSON.stringify(settings));
    }

    loadSettings() {
        const saved = localStorage.getItem('intervalTrainerSettings');
        if (saved) {
            const settings = JSON.parse(saved);
            
            if (settings.scale && document.getElementById('scaleSelect')) {
                document.getElementById('scaleSelect').value = settings.scale;
            }
            if (settings.direction && document.getElementById('directionSelect')) {
                document.getElementById('directionSelect').value = settings.direction;
            }
            if (typeof settings.fixedRoot === 'boolean' && document.getElementById('fixedRoot')) {
                document.getElementById('fixedRoot').checked = settings.fixedRoot;
            }
            if (typeof settings.hideAnswer === 'boolean' && document.getElementById('hideAnswer')) {
                document.getElementById('hideAnswer').checked = settings.hideAnswer;
            }
            if (settings.intervalFilter && document.getElementById('intervalFilter')) {
                document.getElementById('intervalFilter').value = settings.intervalFilter;
            }
            if (typeof settings.randomOrder === 'boolean' && document.getElementById('randomOrder')) {
                document.getElementById('randomOrder').checked = settings.randomOrder;
            }
            if (settings.practiceMode && document.getElementById('practiceMode')) {
                document.getElementById('practiceMode').value = settings.practiceMode;
            }
            if (settings.pianoDirection && document.getElementById('pianoDirection')) {
                document.getElementById('pianoDirection').value = settings.pianoDirection;
            }
            if (typeof settings.pianoFixedRoot === 'boolean' && document.getElementById('pianoFixedRoot')) {
                document.getElementById('pianoFixedRoot').checked = settings.pianoFixedRoot;
            }
            if (settings.pianoTempo && document.getElementById('pianoTempo')) {
                document.getElementById('pianoTempo').value = settings.pianoTempo;
                document.getElementById('pianoTempoValue').textContent = settings.pianoTempo;
                this.pianoTempo = parseInt(settings.pianoTempo);
            }
            if (settings.allIntervalsDirection && document.getElementById('allIntervalsDirection')) {
                document.getElementById('allIntervalsDirection').value = settings.allIntervalsDirection;
            }
            if (settings.allIntervalsTempo && document.getElementById('allIntervalsTempo')) {
                document.getElementById('allIntervalsTempo').value = settings.allIntervalsTempo;
                document.getElementById('allTempoValue').textContent = settings.allIntervalsTempo;
            }
        }
    }
    
    // 播放示范音阶
    async playDemoScale() {
        const baseOctave = parseInt(document.getElementById('pianoOctave').value);
        
        // 更新按钮状态
        const button = document.getElementById('playDemoScale');
        if (button) {
            button.textContent = '⏹️ 停止音阶';
            button.className = 'btn btn-warning btn-lg';
        }
        
        await this.playOctaveScale(baseOctave);
    }
    
    // 停止示范音阶
    stopDemoScale() {
        this.isDemoScalePlaying = false;
        
        // 恢复按钮状态
        const button = document.getElementById('playDemoScale');
        if (button) {
            button.textContent = '🎵 播放示范音阶';
            button.className = 'btn btn-outline-primary btn-lg';
        }
    }
}

// 全局初始化
let trainer;
document.addEventListener('DOMContentLoaded', () => {
    console.log('DOM 加载完成，开始初始化 trainer...');
    trainer = new IntervalTrainer();
    console.log('trainer 实例已创建');
});